﻿@{
    Layout = null;
}
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据采集网关</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script>

    <style>
        /* 全局样式 */
        html,
        body {
            height: 100%;
            margin: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #4e8ef7, #00b8a9);
            /* 清新渐变背景 */
            color: #f1f1f1;
            box-sizing: border-box;
            overflow-x: hidden;
        }

        .container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: calc(100vh - 40px);
            padding: 20px;
            text-align: center;
            max-width: 1200px;
            margin: 0 auto;
            overflow: hidden;
        }

        h2 {
            font-size: 36px;
            font-weight: bold;
            margin-bottom: 20px;
            text-transform: uppercase;
            letter-spacing: 1px;
            color: #ffffff;
            text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.4);
        }

        .message-list {
            width: 100%;
            height: 600px;
            overflow-y: auto;
            padding: 20px;
            border-radius: 10px;
            background-color: rgba(0, 0, 0, 0.6);
            box-shadow: 0 0 20px rgba(0, 255, 204, 0.3);
            margin-bottom: 30px;
            font-size: 16px;
            line-height: 1.8;
            text-align: left;
            /* 设置消息内容靠左显示 */
        }

        .message-item {
            padding: 12px;
            margin-bottom: 8px;
            background-color: rgba(0, 0, 0, 0.3);
            border-radius: 8px;
            transition: all 0.3s ease;
            word-wrap: break-word;
            /* 确保长单词或URL换行 */
        }

        .message-item:hover {
            background-color: rgba(0, 255, 204, 0.2);
            box-shadow: 0 0 15px rgba(0, 255, 204, 0.5);
        }

        .device-list {
            width: 100%;
            padding: 20px;
            border-radius: 10px;
            background-color: rgba(0, 0, 0, 0.6);
            box-shadow: 0 0 20px rgba(0, 255, 204, 0.3);
        }

        .device-grid {
            display: grid;
            grid-template-columns: repeat(6, 1fr);
            gap: 15px;
            justify-items: center;
        }

        .device-card {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: rgba(20, 20, 20, 0.8);
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #00ffcc;
            color: #00ffcc;
            font-weight: bold;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            box-shadow: 0 0 10px rgba(0, 255, 204, 0.4);
        }

        .device-card:hover {
            transform: scale(1.05);
            box-shadow: 0 0 15px rgba(0, 255, 204, 0.5);
        }

        .status-example {
            margin-bottom: 15px;
            font-size: 16px;
            color: #bbb;
        }

        .status {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            display: inline-block;
            box-shadow: 0 0 10px rgba(0, 255, 204, 0.8);
            margin-left: 10px;
        }

        .online {
            background-color: #00ff00;
            box-shadow: 0 0 12px #00ff00;
        }

        .offline {
            background-color: #ff0033;
            box-shadow: 0 0 12px #ff0033;
        }

        /* 媒体查询调整布局 */
        @@media (max-width: 1200px) {
            .device-grid {
                grid-template-columns: repeat(4, 1fr);
            }
        }

        @@media (max-width: 768px) {
            .device-grid {
                grid-template-columns: repeat(3, 1fr);
            }
        }

        @@media (max-width: 480px) {
            .device-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }
    </style>

</head>

<body>

    <div id="app" class="container">
        <h2>数据采集网关</h2>
        <p v-if="message">{{ message }}</p>

        <div class="message-list" ref="messageList">
            <div v-for="(msg, index) in messageHistory" :key="index" class="message-item">
                {{ msg }}
            </div>
        </div>

        <div class="device-list">
            <h3>设备状态</h3>
            <div class="status-example">
                <span class="status online"></span> <span>在线</span> |
                <span class="status offline"></span> <span>离线</span>
            </div>
            <div class="device-grid">
                <div v-for="(status, deviceId) in devices" :key="deviceId" class="device-card">
                    <span>{{ deviceId }}</span>
                    <span :class="['status', status ? 'online' : 'offline']"></span>
                </div>
            </div>
        </div>
    </div>

    <script>
        const { createApp, ref, onMounted, onUnmounted, nextTick } = Vue;

        createApp({
            setup() {
                const loading = ref(false);
                const message = ref('');
                const messageHistory = ref([]);
                const devices = ref({}); // 设备状态字典
                let connection = null;
                const MAX_MESSAGES = 1000;

                // 更新消息历史并滚动到最新
                const updateMessages = (newMessage) => {
                    messageHistory.value.push(newMessage);
                    if (messageHistory.value.length > MAX_MESSAGES) {
                        messageHistory.value.shift(); // 移除最早的一条消息
                    }
                    nextTick(() => {
                        // 滚动到消息列表的底部
                        const messageList = document.querySelector('.message-list');
                        messageList.scrollTop = messageList.scrollHeight;
                    });
                };

                const fetchDeviceStatus = () => {
                    fetch('/api/DataAcquisition/GetPlcConnectionStatus')
                        .then(response => response.json())
                        .then(data => {
                            devices.value = data;
                        })
                        .catch(error => {
                            updateMessages(`获取设备状态失败: ${error}`);
                        });
                };

                // 设置 SignalR 连接
                onMounted(() => {
                    connection = new signalR.HubConnectionBuilder()
                        .withUrl("/dataHub") // SignalR Hub 地址
                        .build();

                    connection.on("ReceiveOpsEvent", (evt) => {
                        // 当从服务器接收到运行事件时，格式化并更新消息
                        updateMessages(`${new Date(evt.timestamp).toLocaleString()} [${evt.level}] ${evt.message}`);
                    });

                    connection.start().then(() => {
                        updateMessages('SignalR 连接已打开');
                    }).catch(err => {
                        updateMessages('SignalR 连接失败', err);
                    });

                    // 每隔2秒获取设备状态
                    fetchDeviceStatus();
                    setInterval(fetchDeviceStatus, 2000);
                });

                // 关闭 SignalR 连接
                onUnmounted(() => {
                    if (connection) {
                        connection.stop();
                    }
                });

                return {
                    loading,
                    message,
                    messageHistory,
                    devices
                };
            }
        }).mount('#app');
    </script>

</body>

</html>
